﻿using RockBus.DataContracts;
using System.Collections.Generic;
using System.ServiceModel.Channels;
using System.Threading.Tasks;
using System.Transactions;
using System.Xml;

namespace RockBus.Messages.Interfaces
{
    public interface IMessageFactory
    {
        Message CreateMessage(XmlReader xmlReader, string action, Message message);

        IMessage CreateMessage(Message message, bool useBuffer);

        IMessage CreateMessage(XmlReader xmlReader, string action, IMessage message);

        void ExtractHeaders(Message requestMessage, out RoutingHeader routingHeader, out CorrelationHeader CorrelationHeader);

        /// <summary>
        /// Creates a request MessageContext
        /// </summary>
        /// <param name="requestMessage"></param>
        /// <param name="transaction"></param>
        /// <param name="tcs"></param>
        /// <param name="publisherExchangeType"></param>
        /// <returns></returns>
        IMessageContext CreateRequestMessageContext(Message requestMessage, Transaction transaction, TaskCompletionSource<Message> tcs, ExchangeTypeEnum publisherExchangeType, ReceivePortInfo receivePortInfo, RoutingHeader routingHeader, CorrelationHeader correlationHeader);

        /// <summary>
        /// Creates a new request context from a response context.
        /// </summary>
        /// <param name="responseMessageContext"></param>
        /// <returns></returns>
        IMessageContext CreateRequestMessageContextFromResponse(IMessageContext responseMessageContext);

        /// <summary>
        /// Creates a response MessageContext
        /// </summary>
        /// <param name="requestMessageContext"></param>
        /// <param name="responseMessage"></param>
        /// <returns></returns>
        IMessageContext CreateResponseMessageContext(IMessageContext requestMessageContext, Message responseMessage);

        IMessageContext CreateFaultMessageContext(IMessageContext requestMessageContext, Message responseMessage);

        IMessageContext CreateMessageContext(XmlReader reader, MessageVersion version);

        /// <summary>
        /// Creates a MessageContext. Request or response is determined by the contents of the RoutingHeader.
        /// </summary>
        /// <param name="requestMessage"></param>
        /// <param name="routingHeader"></param>
        /// <returns></returns>
        IMessageContext CreateMessageContext(Message message, RoutingHeader routingHeader);

        IMessageContext CreatePersistentMessageContext(ProcessingData processingData, IMessage requestMessage, Transaction transaction, IEnumerable<RoutingHeader> persistentRoutingHeaders, TaskCompletionSource<Message> tcs, EvaluationResult evaluationResult, ReceivePortInfo receivePortInfo);

        IMessageContext CreateTransientMessageContext(ProcessingData processingData, IMessage requestMessage, RoutingHeader routingHeader, TaskCompletionSource<Message> tcs, EvaluationResult evaluationResult, ReceivePortInfo receivePortInfo);

        /// <summary>
        /// Creates a System.ServiceModel.Channels.Message from the messageContext.
        /// </summary>
        /// <param name="messageContext"></param>
        /// <returns></returns>
        Message CreateServiceModelMessage(IMessageContext messageContext, RoutingHeader routingHeader, MessageVersion messageVersion, bool addRoutingHeader, bool addCorrelationHeader);

        Message CreatePersistenceMessage(IMessageContext messageContext, RoutingHeader routingHeader, MessageVersion transportMessageVersion);
        IMessageContext CreateMessageContextFromPersistenceMessage(Message persistenceMessage, Transaction transaction, TaskCompletionSource<Message> tcs);
    }
}